package com.jeesite.modules.digitalize.service;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bimface.api.bean.response.FileTranslateBean;
import com.jeesite.common.lang.ObjectUtils;
import com.jeesite.common.lang.StringUtils;
import com.jeesite.modules.digitalize.config.Constants;
import com.jeesite.modules.digitalize.dao.DigitalizeComponentDao;
import com.jeesite.modules.digitalize.entity.DigitalizeComponent;
import com.jeesite.modules.digitalize.entity.DigitalizeComponentVersion;
import com.jeesite.modules.digitalize.entity.ResourceLibrary;
import com.jeesite.modules.digitalize.entity.dto.IdDto;
import com.jeesite.modules.digitalize.entity.dto.component.ComponentAddDto;
import com.jeesite.modules.digitalize.entity.dto.resource.ResourceDelDto;
import com.jeesite.modules.digitalize.entity.dto.resource.ResourceMoveDto;
import com.jeesite.modules.digitalize.entity.vo.component.ComponentRecycleVo;
import com.jeesite.modules.digitalize.entity.vo.component.ConponentsVo;
import com.jeesite.modules.digitalize.util.bimface.BimFaceUtils;
import com.jeesite.modules.digitalize.util.response.ResultStatusCode;
import com.jeesite.modules.digitalize.util.response.ResultVo;
import com.jeesite.modules.sys.entity.User;
import com.jeesite.modules.sys.utils.UserUtils;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * (DigitalizeComponent)表服务实现类
 *
 * @author xk
 * @since 2024-01-03 14:28:17
 */
@Service("digitalizeComponentService")
public class DigitalizeComponentService extends ServiceImpl<DigitalizeComponentDao, DigitalizeComponent> {

    @Resource
    DigitalizeComponentVersionService digitalizeComponentVersionService;
    @Resource
    DigitalizeComponentDao digitalizeComponentDao;

    @Resource
    BimFaceUtils bimFaceUtils;

    /**
     * @date 2024年01月04日 11:12:09
     * @author patronli
     * @Description: 同一个项目id+文件名字标记为同一个构建
     */
    public ResultVo addFloder(ComponentAddDto dto) {
        Integer fileType = dto.getFileType();
        DigitalizeComponent resourceLibrary;
        if (Constants.type_0.equals(fileType)) {//创建的是文件夹
            this.save(new DigitalizeComponent(dto.getParentId(), dto.getProjectCode(), dto.getFileSource(), dto.getFileName(), dto.getFileType()));
        } else {//创建的是文件
            Long componentId;
            String version = "V1";
            //先判断有没有同项目同名文件  同级
            LambdaQueryWrapper<DigitalizeComponent> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(DigitalizeComponent::getProjectCode, dto.getProjectCode());
            queryWrapper.eq(DigitalizeComponent::getFileName, dto.getFileName());
            queryWrapper.eq(DigitalizeComponent::getParentId, dto.getParentId());
            queryWrapper.eq(DigitalizeComponent::getFileSource, dto.getFileSource());
            queryWrapper.eq(DigitalizeComponent::getDelStatus, Constants.DEL_STATUA_0);
            DigitalizeComponent digitalizeComponent = this.getOne(queryWrapper);
            if (digitalizeComponent == null) {//同名文件不存在
                //先新增主表
                DigitalizeComponent component = new DigitalizeComponent(dto.getParentId(), dto.getProjectCode(), dto.getFileSource(), dto.getFileName(), dto.getFileType());
                this.save(component);
                componentId = component.getId();
            } else {
                componentId = digitalizeComponent.getId();
                //去获取当前文件最大的版本号，version+1
                LambdaQueryWrapper<DigitalizeComponentVersion> queryWrapperVersion = new LambdaQueryWrapper<>();
                queryWrapperVersion.eq(DigitalizeComponentVersion::getComponentId, componentId);
                queryWrapperVersion.orderByDesc(DigitalizeComponentVersion::getVersion);
                List<DigitalizeComponentVersion> versions = digitalizeComponentVersionService.list(queryWrapperVersion);
                if (!CollectionUtils.isEmpty(versions)) {
                    version = "V" + (Integer.parseInt(versions.get(0).getVersion().substring(1)) + 1);
                }
            }
            //再新增版本表
            digitalizeComponentVersionService.save(new DigitalizeComponentVersion(componentId, dto.getProjectCode(), dto.getFileSource(), dto.getFileId(), dto.getFileName(), version));
        }
        return ResultVo.success();
    }

    public ResultVo<List<ConponentsVo>> files(String projectCode, Integer fileSource, String fileName) {
        List<ConponentsVo> conponentsVos = new ArrayList<>();
        LambdaQueryWrapper<DigitalizeComponent> eq = new LambdaQueryWrapper<DigitalizeComponent>()
                .eq(DigitalizeComponent::getProjectCode, projectCode)
                .eq(DigitalizeComponent::getFileSource, fileSource)
                .eq(DigitalizeComponent::getDelStatus, Constants.DEL_STATUA_0);
        if (StringUtils.isNotEmpty(fileName)){
            eq.like(DigitalizeComponent::getFileName,fileName);
        }
        //查询主表数据
        List<DigitalizeComponent> digitalizeComponentList = this.list(eq);
        if (digitalizeComponentList.size() > 0) {
            //查询DigitalizeComponentVersion数据然后组装数据
            List<DigitalizeComponentVersion> digitalizeComponentVersionList = digitalizeComponentVersionService.list(new LambdaQueryWrapper<DigitalizeComponentVersion>()
                    .eq(DigitalizeComponentVersion::getProjectCode, projectCode)
                    .eq(DigitalizeComponentVersion::getFileSource, fileSource)
                    .eq(DigitalizeComponentVersion::getDelStatus, Constants.DEL_STATUA_0));
            //component_id为key分组
            Map<Long, List<DigitalizeComponentVersion>> digitalizeComponentMap = digitalizeComponentVersionList.stream().collect(Collectors.groupingBy(DigitalizeComponentVersion::getComponentId));
            //开始组装数据
            for (DigitalizeComponent component : digitalizeComponentList) {
                ConponentsVo conponentsVo = new ConponentsVo(component.getId(), component.getParentId(), component.getFileType(), component.getFileName(), component.getCreateDate());
                List<DigitalizeComponentVersion> digitalizeComponentVersions = digitalizeComponentMap.get(component.getId());
                if (digitalizeComponentVersions != null) {
                    //java8根据id倒叙排序digitalizeComponentVersions
                    Stream<DigitalizeComponentVersion> sorted = digitalizeComponentVersions.stream().sorted(Comparator.comparingLong(DigitalizeComponentVersion::getId).reversed());
                    DigitalizeComponentVersion lastversion = sorted.findFirst().get();
                    conponentsVo.setFileId(lastversion.getFileId());
                    conponentsVo.setTransitionStatus(lastversion.getTransitionStatus());
                    conponentsVo.setVersion(lastversion.getVersion());
                    conponentsVo.setVersions(digitalizeComponentVersions);
                }
                conponentsVos.add(conponentsVo);
            }
            //开始组装树状结构
            conponentsVos = buildDataTree(conponentsVos, Integer.parseInt(Constants.DEFAULT_TOP_PARENT_ID));
        }
        return ResultVo.success(conponentsVos);
    }


    /**
     * @date 2024年01月04日 17:02:32
     * @author patronli
     * @Description: 删除版本
     */
    public ResultVo delVersion(IdDto dto){
        //判断是否为 最后一个版本  如果是最后一个版本 不删除版本 要把外层主表删掉进回收站
        DigitalizeComponentVersion version = digitalizeComponentVersionService.getById(dto.getId());
        if (!ObjectUtils.isEmpty(version)) {
            LambdaQueryWrapper<DigitalizeComponentVersion> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(DigitalizeComponentVersion::getComponentId,version.getComponentId());
            List<DigitalizeComponentVersion> list = digitalizeComponentVersionService.list(lambdaQueryWrapper);
            DigitalizeComponent component = this.baseMapper.selectById(version.getComponentId());
            if (CollectionUtils.isNotEmpty(list) && ObjectUtils.isNotEmpty(component)
                    && component.getFileType().equals(Constants.type_1)) {
                component.setDelBatch(UUID.randomUUID().toString().replaceAll("-", ""));
                component.setDelStatus(Constants.DEL_STATUA_2);
                this.baseMapper.updateStatusById(component,UserUtils.getUser().getId());
            }
        }
        digitalizeComponentVersionService.removeById(dto.getId());
        return ResultVo.success();
    }

    public ResultVo converting(ResourceDelDto dto){
        for (Long id : dto.getIds()) {
            FileTranslateBean convert = bimFaceUtils.convert(id);
            if (ObjectUtils.isEmpty(convert)) {
                return ResultVo.failure("发起转换失败！");
            }
            //批量更新digitalizeComponentVersion状态为转换中
            digitalizeComponentVersionService.update(new LambdaUpdateWrapper<DigitalizeComponentVersion>()
                    .set(DigitalizeComponentVersion::getTransitionStatus, Constants.TRANSITION_STATUS_1)
                    .eq(DigitalizeComponentVersion::getFileId, id)
                    .eq(DigitalizeComponentVersion::getDelStatus, Constants.DEL_STATUA_0));
        }
        return ResultVo.success();
    }

    public ResultVo moveFile(ResourceMoveDto dto){
        List<Long> ids = dto.getIds();
        Integer parentId = dto.getParentId();
        if (ids.contains(Long.valueOf(parentId))) {
            return ResultVo.failure(ResultStatusCode.MOVE_FILE_ERROR_1.getCode(), ResultStatusCode.MOVE_FILE_ERROR_1.getMsg());
        }
        ids.forEach(e -> {
            DigitalizeComponent component = new DigitalizeComponent();
            component.setId(e);
            component.setParentId(parentId);
            this.updateById(component);
        });
        return ResultVo.success();
    }

    public ResultVo delFile(ResourceDelDto dto){
        User user = UserUtils.getUser();
        dto.getIds().forEach(id -> {
            String delBatch = UUID.randomUUID().toString().replaceAll("-", "");
            DigitalizeComponent component = new DigitalizeComponent(Constants.DEL_STATUA_2, delBatch);
            component.setId(id);
            this.baseMapper.updateStatusById(component,user.getId());
            List<ResourceLibrary> childList = digitalizeComponentDao.getChildList(id);
            if (CollUtil.isNotEmpty(childList)) {
                childList.forEach(child -> {
                    DigitalizeComponent childComponent = new DigitalizeComponent(Constants.DEL_STATUA_2, delBatch);
                    childComponent.setId(child.getId());
                    this.baseMapper.updateStatusById(childComponent,user.getId());
                });
            }
        });
        return ResultVo.success();
    }



    public List<ConponentsVo> buildDataTree(List<ConponentsVo> datas, Integer parentId) {
        List<ConponentsVo> source = datas.stream().filter(e -> e.getParentId().equals(parentId)).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(source)) {
            return null;
        }
        List<ConponentsVo> tree = new ArrayList<>();
        source.forEach(item -> {
            if (item.getParentId().equals(parentId)) {
                List<ConponentsVo> children = buildDataTree(datas,  item.getId().intValue());
                tree.add(new ConponentsVo(item.getId(), item.getParentId(), item.getFileType(), item.getFileName(), item.getFileId(), item.getTransitionStatus(), item.getVersion(), item.getCreateDate(), item.getVersions(), children));
            }
        });
        return tree;
    }

    public List<ComponentRecycleVo> getRecycleList(String fileName ,String projectCode) {
        return this.baseMapper.getRecycleList(fileName,projectCode);
    }

    public DigitalizeComponent getByIdAndDelStatus(Integer id) {
        return this.baseMapper.getByIdAndDelStatus(id);
    }

    public void updateByIdAndDelStatus(DigitalizeComponent component) {
        this.baseMapper.updateByIdAndDelStatus(component);
    }

    public void updateDel(DigitalizeComponent component) {
        this.baseMapper.updateDel(component);
    }
}

